/*
 * @Author: zhangqf
 * @Date: 2018-11-26 14:57:40 
 * @Last Modified by: mikey.zhaopeng
 * @Last Modified time: 2019-02-15 12:35:40
 */

import {
  SERVER
} from "@/api/apiConfig.js";
import sessionFun from "@/utils/cc-webapp/login.js";

import axios from 'axios';

var _appId = "";
var _nativeData = "";

function setAppId(appId) {
  _appId = appId
}

//设置应用信息
function setNative(data) {
  _nativeData = data
  // console.log(_nativeData);
}

// 自定义判断元素类型JS
function toType(obj) {
  return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
// 参数过滤函数
function filterNull(o) {
  for (var key in o) {
    if (o[key] === null) {
      delete o[key]
    }
    if (toType(o[key]) === 'string') {
      o[key] = o[key].trim()
    } else if (toType(o[key]) === 'object') {
      o[key] = filterNull(o[key])
    } else if (toType(o[key]) === 'array') {
      o[key] = filterNull(o[key])
    }
  }
  return o
}


/**
 * 区块请求方法
 * @param  {object} url  请求链接
 * @param  {String} params 是否显示区块(默认)
 * @param  {String} returnName 直接返回清单数据
 */
function blockAxios(url, params, returnName) {
  return this.doAxios(url, params, 'GET').then(res => {
    return returnName ? res[returnName] : res
  })
}

// 并发请求方法（多个接口同步同步）
/** 
 * @example
 * this.GLOBAL_.ccRequest
        .allAxios(this.p1(), this.p2(), this.p2())
        .then(reload => {
          console.log("完成");
        });
 */
function allAxios() {
  return axios.all([].slice.call(arguments))
    .then(axios.spread(function (acct, perms) {
      // 两个请求现在都执行完成

      return {
        acct,
        perms
      }

    }));
}

/** 不带session請求方法
 * @param  {string} url 请求url
 * @param  {data} params 请求携带参数
 * @param  {string} method  默认POST  可传入 GET / POST
 */
function doAxios(url, params, method) {
  let m = method ? method : "POST" //默认使用POST

  return new Promise(function (resolve, reject) {

    return apiAxios(m, url, params).then(res => {
      resolve(res)
    }).catch(e => {
      reject(e)
    })

  })

}

/** 带session请求
 * @param  {string} url 请求url
 * @param  {data} params 请求携带参数
 * @param  {string} method  默认POST  可传入 GET / POST
 * @param  {Boolean } isLogin  是否需要跳转login  
 * @param  {string } isSession  外部传入session，   
 * @Examples
 * isLogin 为检查session 当为空的时候是否需要跳转登录页判断，
 * 为兼容以调用过的请求， 所以默认为跳转登录页
 * 按照调用语义 ，调用的时候可传入 ‘no login’
 * doSessionAxios(url, params, method, 'no login')
 * @Examples
 * isSession 为外部传入，默认不传入自动获取本地session，
 * 当前用于新用户注册邮箱预传入，绑定成功才缓存到本地。
 * 
 */
function doSessionAxios(url, params, method, isLogin, isSession) {

  let m = method ? method : "POST" //默认使用POST
  var loginFlag = true

  if (isLogin) {
    loginFlag = false
  }


  return new Promise(function (resolve, reject) {

    //如果存在外部传入session就使用外部的
    if (isSession) {

      return apiAxios(m, url, params, isSession).then(res => {
        resolve(res)

      }).catch(e => {
        if (e.response.status == 500) {
          native.showToast("網絡請求失敗");
        }

        if (e.response.data.code == 40101) {
          native.removeStorage('app_session');
          native.showToast("用戶已過期請退出重新登錄");
          sessionFun.go()

        } else if (e.response.data.code == 40102) {

          native.showToast("該用戶已被系統停用");

        } else {
          reject(e)
        }
      })

    } else {

      return sessionFun.get(loginFlag).then(w_session => {

        //不跳登錄頁且沒有獲取到session時
        if (loginFlag && w_session.session == null) {
          let e = {
            isLogin: false
          }
          reject(e)
        }


        return apiAxios(m, url, params, w_session).then(res => {
          resolve(res)

        }).catch(e => {
          if (e.response.status == 500) {
            native.showToast("網絡請求失敗");
          }

          if (e.response.data.code == 40101) {
            native.removeStorage('app_session');
            native.showToast("用戶已過期請退出重新登錄");
            sessionFun.go()

          } else if (e.response.data.code == 40102) {

            native.showToast("該用戶已被系統停用");

          } else {
            reject(e)
          }
        })

      })

    }


  })

}



// 底层请求方法
function apiAxios(method, url, params, app_session) {

  return new Promise(function (resolve, reject) {
    var sendUrl = SERVER.URL + url


    //填入設備類型參數
    params.clientType = _nativeData.system


    //过滤空参数
    if (params) {
      params = filterNull(params)
    }

    //传入APPID 参数
    if (!params.appId) {
      params.appId = _appId
    }

    let obj = {}
    obj['method'] = method
    obj['url'] = sendUrl
    obj['data'] = method === 'POST' || method === 'PUT' ? params : null
    obj['params'] = method === 'GET' || method === 'DELETE' ? params : null
    obj['headers'] = {
      'Content-type': 'application/x-www-form-urlencoded',
      'clientType': _nativeData.system,
      'versionCode': _nativeData.versionCode,
      'appVersion': _nativeData.appVersion,
      'deviceId': _nativeData.deviceId,
      'network': _nativeData.networkStatus,
    }

    if (app_session) {
      obj['headers']['session'] = app_session.session
    }

    obj['withCredentials'] = false
    obj['transformRequest'] = [function (data) {
      //post 請求不格式化
      // if (method == "POST") {
      //   console.log("data", data)
      //   return data;
      // }
      let ret = ''
      for (let it in data) {
        if (data[it] instanceof Array) {
          // 数组
          for (let item in data[it]) {
            ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it][item]) + '&'
          }
        } else {
          ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
        }
      }
      return ret
    }]

    axios(obj).then((res) => {
      resolve(res.data)
    }).catch((err) => {
      reject(err)
    })

  })

}


function merge(url, obj) {

  //構造請求體
  let postD = [];
  for (let i in obj) {
    let d = {
      id: i
    }
    let item = obj[i];
    let u = item.url + "?"
    let pStr = '';
    for (let p in item.param) {
      let pVal = item.param[p];
      if (typeof (pVal) === "Object") {
        pStr += `&${p}=${JSON.stringify(pVal)}`
      } else {
        pStr += `&${p}=${pVal}`
      }
    }
    u += pStr;
    d.url = u;
    postD.push(d)

  }
  url += "?data=" + encodeURIComponent(JSON.stringify(postD)); //不知道為什麼，反正這樣可以



  return apiAxios("GET", url, {}).then(res => {

    //將結果裝入OBJ
    for (let idx in res) {
      let id = res[idx].id;
      obj[id].data = res[idx].result
    }
    return obj
  }).catch(e => {

    // console.log(e);


    return e
  })



}

export default {
  setAppId,
  doAxios,
  blockAxios,
  allAxios,
  merge,
  doSessionAxios,
  setNative,
}
